import java.util.LinkedList;
import java.util.Queue;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

class Elevator {
    enum State {
        OPENING, OPENED, CLOSING, CLOSED, WAITING, MOVING, DECELERATING
    }

    private static final int TOTAL_FLOORS = 8; // 楼层数量
    private static final int BASE_FLOOR = 1; // 电梯返回的基准层
    private int currentFloor = BASE_FLOOR; // 电梯初始在1层
    private State currentState = State.WAITING; // 初始状态为等待
    private Queue<Request> requests = new LinkedList<>(); // 请求队列
    private ElevatorGUI gui; // 传递给 Elevator 的 GUI 界面引用
    private int peopleCount = 0; // 当前电梯内的人数
    private static final int MAX_PEOPLE = 12; // 电梯人数上限

    public Elevator(ElevatorGUI gui) {
        this.gui = gui; // 设置 GUI 引用
    }

    public void addRequest(Request request) {
        requests.add(request);
    }

    public Request pollRequest() {
        return requests.poll(); // 获取下一个请求
    }

    public void moveTo(int targetFloor) {
        currentState = State.MOVING; // 更新状态为移动中
        gui.updateStateLabel("电梯状态: 移动中");

        int direction = (currentFloor < targetFloor) ? 1 : -1; // 确定移动方向
        gui.updateDirection(direction == 1 ? "↑" : "↓"); // 更新电梯方向

        while (currentFloor != targetFloor) {
            // 减速处理：即将到达目标楼层时，更新状态为减速
            if (Math.abs(currentFloor - targetFloor) == 1) {
                currentState = State.DECELERATING; // 更新状态为减速
                gui.updateStateLabel("电梯状态: 减速中");
                delay(1000); // 模拟减速
            }

            currentFloor += direction; // 移动一层
            updateStateForMovement(direction == 1 ? "↑" : "↓"); // 更新状态
            delay(700); // 模拟电梯移动的时间
        }

        currentState = State.WAITING; // 更新状态为等待
        gui.updateStateLabel("电梯状态: 等待中");
    }

    private void updateStateForMovement(String direction) {
        SwingUtilities.invokeLater(() -> {
            gui.updateElevatorStatus(currentFloor + " " + direction); // 更新电梯状态
            gui.updateLog("电梯正在" + (direction.equals("↑") ? "上升" : "下降") + "，当前楼层：" + currentFloor); // 在日志中记录状态
            gui.updateElevatorPosition(currentFloor); // 更新电梯位置
        });
    }

    public void openDoor() {
        currentState = State.OPENING; // 更新状态为正在开门
        SwingUtilities.invokeLater(() -> {
            gui.updateLog("电梯正在开门");
            gui.updateStateLabel("电梯状态: 正在开门");
        });

        // 使用 Timer 来模拟门的开合动画
        Timer openTimer = new Timer(25, null); // 每 25ms 更新一次
        openTimer.addActionListener(e -> {
            gui.updatePeopleCountLabel(); // 更新电梯人数显示
            openTimer.stop(); // 结束开门动画
        });
        openTimer.start();

        delay(250); // 开门需要 25t (250ms)
        currentState = State.OPENED; // 更新状态为门已打开
        SwingUtilities.invokeLater(() -> {
            gui.updateLog("电梯门已打开");
            gui.updateStateLabel("电梯状态: 门已打开");
        });
    }

    public void handlePeopleInOut(int enterCount, int exitCount) {
        SwingUtilities.invokeLater(() -> {
            // 进入人员
            if (enterCount > 0) {
                if (peopleCount + enterCount <= MAX_PEOPLE) {
                    peopleCount += enterCount;
                    gui.updateLog(enterCount + "人进电梯");
                } else {
                    gui.updateLog("电梯已满，无法再进人");
                }
            }

            // 出去人员
            if (exitCount > 0) {
                if (peopleCount >= exitCount) {
                    peopleCount -= exitCount;
                    gui.updateLog(exitCount + "人出电梯");
                } else {
                    gui.updateLog("电梯内没有足够的人出");
                }
            }

            gui.updatePeopleCountLabel(); // 更新电梯人数显示
        });
    }

    public void closeDoor() {
        currentState = State.CLOSING; // 更新状态为正在关门
        SwingUtilities.invokeLater(() -> {
            gui.updateLog("电梯正在关门");
            gui.updateStateLabel("电梯状态: 正在关门");
        });
        delay(250); // 关门需要 25t (250ms)
        currentState = State.CLOSED; // 更新状态为门已关闭
        SwingUtilities.invokeLater(() -> {
            gui.updateLog("电梯门已关闭");
            gui.updateStateLabel("电梯状态: 门已关闭");
        });
    }

    public void returnToBase() {
        currentState = State.MOVING; // 更新状态为移动中
        SwingUtilities.invokeLater(() -> {
            gui.updateLog("电梯正在返回1层...");
            gui.updateStateLabel("电梯状态: 返回1层");
            gui.updateDirection("↓"); // 设置电梯方向为下降
        });

        new Thread(() -> {
            while (currentFloor > BASE_FLOOR) {
                currentFloor--;
                SwingUtilities.invokeLater(() -> {
                    gui.updateElevatorPosition(currentFloor); // 更新电梯位置
                    gui.updateLog("电梯正在下降，当前楼层：" + currentFloor);
                });
                delay(700); // 模拟每一层的移动延迟
            }
            currentState = State.WAITING; // 更新状态为等待
            SwingUtilities.invokeLater(() -> {
                gui.updateLog("电梯已返回1层");
                gui.updateElevatorStatus(currentFloor + " 等待"); // 显示电梯在 1 楼等待
                gui.updateStateLabel("电梯状态: 等待");
                gui.updateDirection("等待");
            });
        }).start(); // 启动新线程来处理返回的动画
    }

    private void delay(int millis) {
        try {
            Thread.sleep(millis); // 模拟延迟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public int getCurrentFloor() {
        return currentFloor; // 获取当前楼层
    }

    public State getCurrentState() {
        return currentState; // 返回当前状态
    }

    public int getPeopleCount() {
        return peopleCount; // 获取电梯内人数
    }

    public void incrementPeopleCount() {
        if (peopleCount < MAX_PEOPLE) {
            peopleCount++; // 增加电梯内人数
        }
    }

    public void decrementPeopleCount() {
        if (peopleCount > 0) {
            peopleCount--; // 减少电梯内人数
        }
    }
}
